package com.betterjr.modules.accountSupervision.utils;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.config.annotation.Reference;
import com.betterjr.common.utils.BTAssert;
import com.betterjr.modules.customer.ICustOpenAccountService;
import com.betterjr.modules.customer.entity.CustBaseConfigure;
import com.betterjr.modules.risk.loanmanage.remote.TransferService;
import com.caucho.hessian.client.HessianProxyFactory;
import org.apache.commons.collections.CollectionUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.text.SimpleDateFormat;
import java.util.*;
@Component
public class ScfRomoteUtil {
    private static Logger logger = LoggerFactory.getLogger(ScfRomoteUtil.class);
    private static ScfRomoteUtil romoteUtil;
    // 引用 客户管理-基础配置，根据id 查询
    @Reference(interfaceClass = ICustOpenAccountService.class)
    private static ICustOpenAccountService custOpenAccountService;
    // 获取云资金系统的配置接口地址
     private final static String corpCode = getSysFlag();// 系统标识
//     final static String url = "http://192.168.0.131:8888/cpf/service";//系统服务器地址
     private final static String url = getInterfaceAddress();
//     final static String url = "http://127.0.0.1/platform/service";
    public static String CONSTANT_ACCOUNT_MONITOR_WSDL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><header><reqTime></reqTime><tradeCode></tradeCode><serialId></serialId></header><body><entity><id></id><paymentType></paymentType><paymentMode></paymentMode><amount></amount><paymentdate></paymentdate><paymentCustomerId></paymentCustomerId><paymentAccountName></paymentAccountName><paymentAccountNo></paymentAccountNo><paymentAccountBank></paymentAccountBank><paymentBankNo></paymentBankNo><paymentAccounts></paymentAccounts><receiveAccountName></receiveAccountName><receiveAccountNo></receiveAccountNo><receiveAccountBank></receiveAccountBank><receiveBankNo></receiveBankNo><ruleJson></ruleJson></entity><list></list></body></request>";
    public static String CONSTANT_QUERY_BALANCE_WSDL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><header><reqTime></reqTime><tradeCode></tradeCode><corpCode></corpCode><serialId></serialId></header><body><entity></entity><list><accountCode></accountCode></list></body></request>";
    public static String CONSTANT_QUERY_DTL_WSDL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><header><reqTime></reqTime><tradeCode></tradeCode><corpCode></corpCode><serialId></serialId></header><body><entity><accountCode></accountCode><startDate></startDate><endDate></endDate></entity><list></list></body></request>";
    public static String CONSTANT_QUERY_DTL_MONTH_WSDL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><header><reqTime></reqTime><tradeCode></tradeCode><corpCode></corpCode><serialId></serialId></header><body><entity><accountCode></accountCode><tradeDate></tradeDate></entity><list></list></body></request>";

    @PostConstruct
    public void init() {
        romoteUtil = this;
        romoteUtil.custOpenAccountService = this.custOpenAccountService;
    }

    public static void main(final String[] args) {
        final Map<String, Object> datas = new HashMap<>();
        Map<String, Object> result = new HashMap<>();
        datas.put("accountCode", "11005577115901");
        datas.put("custId","3333");
        // callService(url, "PlanRepaymentCpf", null);
        result = callService("QueryCurBalCpf", datas, ScfRomoteUtil.CONSTANT_QUERY_BALANCE_WSDL);
        System.out.print(result.get("remainMoney"));
    }

    /** 
     * @Title: callService 
     * @Description: 调用云资金接口
     * @param tradeCode  服务code ，与云资金约定
     * @param datas  map 数据
     * @param wsdlStr 何种报文格式，有时间可以去掉，自动根据map 生成
     * @return 返回
     * @throws 
     * @author licz
     * @date 2018年7月3日 下午2:25:25 
     */
    public static Map<String, Object> callService(final String tradeCode, final Map<String, Object> datas,
            final String wsdlStr) {
        BTAssert.notNull(datas.get("supplierId"));
        final CustBaseConfigure custBaseConfigure = getCustBaseConfigureInfo(Long.parseLong(datas.get("supplierId").toString()),"2");// 2资金管理云平台
        final String corpCode = custBaseConfigure.getSystemIdentifition();// 系统标识 //"bytter_1000"
        final String url = custBaseConfigure.getServicerUrl() + "/cpf/service";// 系统服务器地址
        datas.put("corpCode", corpCode);// C_CUST_IDENTIFITION 客户标识，云资金对接

        // 认证
        System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
        final HostnameVerifier hv = new HostnameVerifier() {
            @Override
            public boolean verify(final String urlHostName, final SSLSession session) {
                return urlHostName.equals(session.getPeerHost());
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
        // 创建HessianProxyFactory实例
        final HessianProxyFactory factory = new HessianProxyFactory();
        // 获得Hessian服务的远程引用
        try {
            final String reqData = getReqData(tradeCode, datas, wsdlStr);
            final TransferService ts = (TransferService) factory.create(TransferService.class, url);
            final String result = ts.transfer(datas.get("corpCode").toString(), reqData);
            logger.debug("回应结果：" + result);
            final Map<String, Object> mapResult = new HashMap<>();
            mapResult.put("data", ScfXmlUtil.getDetailList1(ScfXmlUtil.getElNameText(result, "body")));
            mapResult.put("code", ScfXmlUtil.getElNameText(result, "retCode"));
            mapResult.put("message", ScfXmlUtil.getElNameText(result, "retMsg"));
//            if (!"0".equals(mapResult.get("code"))) {
//                // 处理失败了
//                BTAssert.isTrue(false, "云资金处理失败：" + mapResult.get("message"));
//            }
            return mapResult;
        }
        catch (final Exception e1) {
            logger.error("call 云资金系统失败", e1);
        }
        return null;
    }

    private static String getReqData(final String tradeCode, final Map<String, Object> datas, final String wsdlStr) {
        final SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        final SimpleDateFormat formatSerial = new SimpleDateFormat("yyyyMMddhhmmsss");

        final Document doc = ScfXmlUtil.parseXML(wsdlStr);
        final Element root = doc.getRootElement();
        final Element head = root.element("header");

        final Element tradeCodeE = head.element("tradeCode");
        final Element reqTimeE = head.element("reqTime");
        final Element serialIdE = head.element("serialId");
        final Element corpCode = head.element("corpCode");

        tradeCodeE.setText(tradeCode);
        reqTimeE.setText(formatDate.format(new Date()));
        serialIdE.setText(formatSerial.format(new Date()));
        corpCode.setText(datas.get("corpCode").toString());

        final Element body = root.element("body");
        final Element entity = body.element("entity");

        for (final Iterator it = entity.elementIterator(); it.hasNext();) {
            final Element element = (Element) it.next();
            if (datas.containsKey(element.getName())) {
                element.setText(datas.get(element.getName()).toString());
            }
        }

        final Element list = body.element("list");

        for (final Iterator it = list.elementIterator(); it.hasNext();) {
            final Element element = (Element) it.next();
            if (datas.containsKey(element.getName())) {
                element.setText(datas.get(element.getName()).toString());
            }
        }

        return doc.asXML();
    }

    public static CustBaseConfigure getCustBaseConfigureInfo(final Long custNo, final String serviceType) {
        final List<CustBaseConfigure> resultList = romoteUtil.custOpenAccountService.queryCustBaseConfigureInfo(custNo,
                serviceType);
        BTAssert.isTrue(!CollectionUtils.isEmpty(resultList), "查询不到客户配置信息custNo:" + custNo);
        return resultList.get(0);
    }
    // 系统标识 TODO
    private static String getSysFlag() {
        // custBaseCfgService
        return "bytter_1000";
    }

    // 系统服务器地址 TODO
    private static String getInterfaceAddress() {
        // custBaseCfgService
//        String url = "https://192.168.0.131/cpf/service";
        String url = "https://192.168.0.43/cpf/service";
        return url;
    }
}
